/**
 * 智能压缩历史消息相关功能
 */
import { ChatMessage, Entity, EntityType } from '../core/types.ts';
import { countTokensInMessages, estimateTokenCount } from './tokenCounter.ts';
import { generateUniqueId, groupMessagesByTurn } from './conversationUtils.ts';
import { entityManager } from './entityExtractor.ts';

/**
 * 提取重要实体并生成实体总结
 * @param entities 实体列表
 * @returns 实体总结字符串
 */
export function generateEntitySummary(entities: Entity[]): string {
    if (entities.length === 0) return '';

    // 按重要性排序并去重
    const uniqueEntities = entities
        .sort((a, b) => b.importance - a.importance)
        .filter((entity, index, self) =>
            index === self.findIndex(e => e.text === entity.text)
        )
        .slice(0, 10); // 最多保留10个实体

    return uniqueEntities
        .map(entity => `${entity.text}(${EntityType[entity.type] || '概念'})`)
        .join(', ');
}

/**
 * 总结对话内容，提取关键主题
 * @param messages 消息列表
 * @param maxTokens 最大token数
 * @returns 总结文本
 */
export function summarizeConversation(messages: ChatMessage[], maxTokens: number): string {
    if (messages.length === 0) return '';

    // 提取每轮对话的主题
    const topics: string[] = [];

    for (let i = 0; i < messages.length; i += 2) {
        const userMsg = messages[i]?.content || '';
        const aiMsg = messages[i + 1]?.content || '';

        // 提取用户问题的前30个字符作为主题
        if (userMsg) {
            const topic = userMsg.length > 30 ? userMsg.substring(0, 30) + '...' : userMsg;
            topics.push(`用户询问: ${topic}`);
        }

        // 简化AI回答
        if (aiMsg) {
            // 提取第一句话
            const firstSentence = aiMsg.split(/[。.!?！？]/)[0];
            if (firstSentence && firstSentence.length > 0) {
                const simplifiedResponse = firstSentence.length > 40 ?
                    firstSentence.substring(0, 40) + '...' : firstSentence;
                topics.push(`AI回复: ${simplifiedResponse}`);
            }
        }
    }

    // 组合结果，确保不超过token限制
    let result = '';
    let currentTokens = 0;

    for (const topic of topics) {
        const topicTokens = estimateTokenCount(topic);
        if (currentTokens + topicTokens <= maxTokens) {
            result += (result ? '\n' : '') + topic;
            currentTokens += topicTokens;
        } else {
            break;
        }
    }

    return result;
}

/**
 * 根据消息重要性对较早的消息进行分类
 * @param messages 消息列表
 * @param entities 实体列表
 * @returns 按重要性分类的消息
 */
function categorizeMessagesByImportance(messages: ChatMessage[], entities: Entity[]): {
    highImportance: ChatMessage[],
    mediumImportance: ChatMessage[],
    lowImportance: ChatMessage[]
} {
    // 获取高重要性实体（重要性 > 7）
    const highImportanceEntities = entities.filter(e => e.importance > 7);

    // 获取中等重要性实体（重要性 4-7）
    const mediumImportanceEntities = entities.filter(e => e.importance >= 4 && e.importance <= 7);

    // 创建结果对象
    const result = {
        highImportance: [] as ChatMessage[],
        mediumImportance: [] as ChatMessage[],
        lowImportance: [] as ChatMessage[]
    };

    // 对每条消息进行分类
    messages.forEach(message => {
        // 检查消息是否包含高重要性实体
        const containsHighImportanceEntity = highImportanceEntities.some(entity =>
            message.content.includes(entity.text));

        // 检查消息是否包含中等重要性实体
        const containsMediumImportanceEntity = mediumImportanceEntities.some(entity =>
            message.content.includes(entity.text));

        // 基于实体出现情况对消息进行分类
        if (containsHighImportanceEntity) {
            result.highImportance.push(message);
        } else if (containsMediumImportanceEntity) {
            result.mediumImportance.push(message);
        } else {
            result.lowImportance.push(message);
        }
    });

    return result;
}

/**
 * 生成分层的对话摘要
 * @param olderMessages 较早的消息
 * @param entities 实体列表
 * @param availableSummaryTokens 可用于摘要的token数
 * @returns 摘要消息数组
 */
function generateLayeredSummary(
    olderMessages: ChatMessage[],
    entities: Entity[],
    availableSummaryTokens: number
): ChatMessage[] {
    if (olderMessages.length === 0 || availableSummaryTokens <= 100) {
        return [];
    }

    // 按重要性对消息进行分类
    const categorizedMessages = categorizeMessagesByImportance(olderMessages, entities);

    // 创建摘要消息数组
    const summaryMessages: ChatMessage[] = [];

    // 分配token预算
    // 高重要性: 50%, 中等重要性: 30%, 实体概述: 20%
    const highImportanceTokens = Math.floor(availableSummaryTokens * 0.5);
    const mediumImportanceTokens = Math.floor(availableSummaryTokens * 0.3);
    const entitySummaryTokens = Math.floor(availableSummaryTokens * 0.2);

    // 为高重要性消息生成详细摘要
    if (categorizedMessages.highImportance.length > 0) {
        const highImportanceSummary = summarizeConversation(
            categorizedMessages.highImportance,
            highImportanceTokens
        );

        if (highImportanceSummary) {
            summaryMessages.push({
                id: generateUniqueId(),
                role: 'system' as const,
                content: `以下是重要对话的详细概述: ${highImportanceSummary}`
            });
        }
    }

    // 为中等重要性消息生成简要摘要
    if (categorizedMessages.mediumImportance.length > 0) {
        const mediumImportanceSummary = summarizeConversation(
            categorizedMessages.mediumImportance,
            mediumImportanceTokens
        );

        if (mediumImportanceSummary) {
            summaryMessages.push({
                id: generateUniqueId(),
                role: 'system' as const,
                content: `以下是一般对话的简要概述: ${mediumImportanceSummary}`
            });
        }
    }

    // 生成实体概述
    if (entities.length > 0) {
        const entitySummary = generateEntitySummary(entities);

        if (entitySummary) {
            summaryMessages.push({
                id: generateUniqueId(),
                role: 'system' as const,
                content: `当前对话中的关键概念: ${entitySummary}`
            });
        }
    }

    return summaryMessages;
}

/**
 * 智能压缩历史消息，保留关键上下文
 * @param messages 历史消息数组
 * @param maxTokens 最大允许的token数
 * @param pinnedMessages 固定消息的索引数组，这些消息不会被压缩
 * @param recentTurnsToKeep 保留的最近对话轮数，默认为15
 * @returns 压缩后的消息数组
 */
export function intelligentCompressHistory(
    messages: ChatMessage[],
    maxTokens: number = 4000,
    pinnedMessages: number[] = [],
    recentTurnsToKeep: number = 15
): ChatMessage[] {
    if (!messages.length) return [];
    if (maxTokens <= 0) return [];

    // 计算所有消息的token数
    const allMessagesTokenCount = countTokensInMessages(messages);

    // 如果总token数已经在限制范围内，直接返回所有消息
    if (allMessagesTokenCount <= maxTokens) {
        return messages;
    }

    // 提取固定的消息，并保留它们的原始索引信息
    const pinnedMessagesWithIndices = pinnedMessages
        .filter(idx => idx >= 0 && idx < messages.length)
        .map(idx => ({ message: messages[idx], originalIndex: idx }));

    // 计算固定消息占用的token数
    const pinnedTokenCount = pinnedMessagesWithIndices.reduce(
        (sum, item) => sum + estimateTokenCount(item.message.content),
        0
    );

    // 计算剩余可用的token数
    const remainingTokens = Math.max(0, maxTokens - pinnedTokenCount);

    // 如果固定消息已经超出token限制，只返回固定消息（按原始顺序）
    if (pinnedTokenCount >= maxTokens) {
        // 按照原始索引排序后返回固定消息
        return pinnedMessagesWithIndices
            .sort((a, b) => a.originalIndex - b.originalIndex)
            .map(item => item.message);
    }

    // 创建固定消息索引集合，用于快速查找
    const pinnedIndices = new Set(pinnedMessages);

    // 提取所有非固定消息
    const nonPinnedMsgs = messages.filter((_, idx) => !pinnedIndices.has(idx));

    // 按对话轮次分组 (一轮是用户提问+AI回答)
    const turns: ChatMessage[][] = groupMessagesByTurn(nonPinnedMsgs);

    // 提取关键实体
    const entities: Entity[] = [];
    for (let i = 0; i < nonPinnedMsgs.length; i++) {
        const msg = nonPinnedMsgs[i];
        const extractedEntities = entityManager.extractEntities(msg.content, i);
        entities.push(...extractedEntities);
    }

    // 最近的消息直接保留，根据配置的保留轮数
    const recentTurns = turns.slice(-recentTurnsToKeep);
    const recentMessages = recentTurns.flat();

    // 计算近期消息的token数
    const recentTokenCount = countTokensInMessages(recentMessages);

    // 剩余可用于总结的token数
    const summaryTokens = Math.max(0, remainingTokens - recentTokenCount);

    // 需要总结的较早消息
    const olderTurns = turns.slice(0, -recentTurnsToKeep);
    const olderMessages = olderTurns.flat();

    // 生成可能的总结消息
    let summaryMessages: ChatMessage[] = [];

    if (olderMessages.length > 0 && summaryTokens > 100) { // 确保有足够token进行总结
        // 使用分层摘要策略
        summaryMessages = generateLayeredSummary(olderMessages, entities, summaryTokens);
    }

    // 确保总结消息不超过剩余token数
    while (summaryMessages.length > 0 &&
        countTokensInMessages(summaryMessages) > summaryTokens) {
        summaryMessages.pop();
    }

    // 组合最终结果
    const result: ChatMessage[] = [];
    const includedIndices = new Set<number>();

    // 首先添加摘要消息（如果有）
    if (summaryMessages.length > 0) {
        result.push(...summaryMessages);
    }

    // 然后按原始顺序添加固定消息
    pinnedMessagesWithIndices
        .sort((a, b) => a.originalIndex - b.originalIndex)
        .forEach(item => {
            result.push(item.message);
            includedIndices.add(item.originalIndex);
        });

    // 最后添加最近的消息（如果它们不是固定消息）
    for (let i = 0; i < messages.length; i++) {
        // 跳过已经添加的固定消息
        if (includedIndices.has(i)) {
            continue;
        }

        // 检查当前消息是否在最近消息中
        const isRecentMessage = recentMessages.some(msg =>
            msg.content === messages[i].content &&
            msg.role === messages[i].role
        );

        if (isRecentMessage) {
            result.push(messages[i]);
        }
    }

    return result;
} 